#pragma once

static GLfloat _table_vertices[] = {
		// rrder of coordinates: x, y, s, t
        // triangle fan
         0.0f,  0.0f, 	0.5f, 0.5f, 
        -0.5f, -0.8f,   0.0f, 0.9f,  
         0.5f, -0.8f,   1.0f, 0.9f, 
         0.5f,  0.8f,   1.0f, 0.1f, 
        -0.5f,  0.8f,   0.0f, 0.1f, 
        -0.5f, -0.8f,   0.0f, 0.9f,
};

class table {
public:
	// table bounder
	const float LEFT_BOUND = -0.5f;
	const float RIGHT_BOUND = 0.5f;
	const float FAR_BOUND = -0.8f;
	const float NEAR_BOUND = 0.8f;

public:
	void
	binddata() {
		GLsizei stride = sizeof(GLfloat) * 4;
		glEnableVertexAttribArray(0);
		glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, stride, _table_vertices);
		
		glEnableVertexAttribArray(1);
		glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, stride, _table_vertices + 2);
	}
	
	void 
	draw() {
		glDrawArrays(GL_TRIANGLE_FAN, 0, 6);
	}

	point
	restrict_blue_mallet(float x, float y, float z, float radius) {
		float rx = math_fclampf(x, LEFT_BOUND + radius, RIGHT_BOUND - radius);
		float rz = math_fclampf(z, 0 + radius, NEAR_BOUND - radius); // half table
		return point(rx, y, rz);
	}

	void 
	restrict_puck(point &puckpos, vector &puckdir, float radius) {
		// if the puck struck a side, reflect it off that side.
        if (puckpos.x < LEFT_BOUND + radius || puckpos.x > RIGHT_BOUND - radius) {
            puckdir = vector(-puckpos.x, puckpos.y, puckpos.z);
            puckdir = puckdir.scale(0.9f); // when reflect, the 0.9 to add friction to slow down the puck
        }        
        if (puckpos.z < FAR_BOUND + radius || puckpos.z > NEAR_BOUND - radius) {
            puckdir = vector(puckdir.x, puckdir.y, -puckdir.z);
            puckdir = puckdir.scale(0.9f);
        }

        puckpos = point(
            math_fclampf(puckpos.x, LEFT_BOUND + radius, RIGHT_BOUND - radius),
            puckpos.y,
            math_fclampf(puckpos.z, FAR_BOUND + radius, NEAR_BOUND - radius)
        );
	}
};